import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class GamePanel extends JPanel {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	public static final int NORTH = 0;
	public static final int SOUTH = 1;
	public static final int EAST = 2;
	public  static final int WEST = 3;
	
	public static final int DEFAULT_TILE_PIXEL_BASE = 16;
	
	private int scale;
		
	private Sprite avatar;
	private Map map; 
	private boolean firstRun;
		
	ArrayList<Action> actionList;
		
	/**
	 * @param fileName
	 */
	public GamePanel(String fileName, int scale){
		avatar = new Sprite();
		map = this.loadMap(fileName);
		actionList = this.loadActionList(map.getActionListFileName());
		this.scale = scale;
		this.setSize(map.getColLength() * DEFAULT_TILE_PIXEL_BASE * scale, 
				     map.getRowLength() * DEFAULT_TILE_PIXEL_BASE * scale);
		firstRun = true;
	}
	private ArrayList<Action> loadActionList(String fileName){
		ArrayList<Action> actionList = new ArrayList<Action>(); 
		ActionLoader actionLoader = new ActionLoader(); //Loads the actions from a file
		actionLoader.setFileName(fileName);//specifies the file name 
		actionLoader.openFile();           // open the file
		actionList = actionLoader.readActionList(); //read in the action list and apply it this action list
		actionLoader.closeFile(); // close the file
		return  actionList;
	}
	private Map loadMap(String fileName){
		MapLoader mapLoader = new MapLoader();
		mapLoader = new MapLoader();
		mapLoader.setFileName(fileName);
		mapLoader.openFile();
		map = mapLoader.readMap();
		mapLoader.closeFile();
		
		return map;
	}
	/**
	 * @see javax.swing.JComponent#paintComponent(java.awt.Graphics)
	 */
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		g.drawImage(getBackgroundImage(),0,0,
					map.getColLength() * DEFAULT_TILE_PIXEL_BASE * scale, 
					map.getRowLength() * DEFAULT_TILE_PIXEL_BASE *scale, null);
			
		this.paintSpriteLayer(g);
			
	}
	
	public void update(Graphics g){
		super.update(g);
		System.out.println("Update");
		this.paintSpriteLayer(g);
	}
	
	/**
	 * @return the image that will be used as the GameFrame's background
	 */
	private Image getBackgroundImage(){
		String fileName = map.getBgImageName();
		
		Image img = null;
		try {
		    img = ImageIO.read(new File(fileName));
		} catch (IOException e) {
			System.err.println("Did not retrieve Background image");
		}
		return img;
	}
	
	
	public void paintSpriteLayer(Graphics g){
		if(firstRun == true){
			avatar.setCol(map.getHeroStartCol());
			avatar.setRow(map.getHeroStartRow());
			firstRun = false;
		}
		g.drawImage(avatar.getAvatarImage(), 
				    avatar.getCol() * map.getTileBase() * scale,
				    avatar.getRow() * map.getTileBase() * scale, 
				    DEFAULT_TILE_PIXEL_BASE * scale, 
				    DEFAULT_TILE_PIXEL_BASE *scale, null);
	}
	
	public void changeMap()
	{}
	
	
	
	public Point moveDirection(int direction){
		
		Point playersCurrentPoint = new Point();
		
		Tile tile = new Tile();
		int row = avatar.getRow();
		int col = avatar.getCol();
		
		int moveIncrement = 1;
		
		Exit exit = new Exit();
		
		tile = map.getTileAt(row, col);
		switch(direction){
			case GamePanel.NORTH:
				if(avatar.getCurrentFace() == GamePanel.NORTH){
					if(tile.isDirection(direction)){
						row -= moveIncrement;
						avatar.setRow(row);}
				}
				else
					avatar.setCurrentFace(GamePanel.NORTH);
				break;
			case GamePanel.SOUTH:
				if(avatar.getCurrentFace() == GamePanel.SOUTH){
					if(tile.isDirection(direction)){
						row += moveIncrement;
						avatar.setRow(row);}
				}
				else
					avatar.setCurrentFace(GamePanel.SOUTH);
				break;
			case GamePanel.EAST:
				if(avatar.getCurrentFace() == GamePanel.EAST){
					if(tile.isDirection(direction)){
						col += moveIncrement;
						avatar.setCol(col);}
				}
				else
					avatar.setCurrentFace(GamePanel.EAST);
				break;
			case GamePanel.WEST:
				if(avatar.getCurrentFace() == GamePanel.WEST){
					if(tile.isDirection(direction)){
						col -= moveIncrement;
						avatar.setCol(col);}
				}
				else
					avatar.setCurrentFace(GamePanel.WEST);
				break;
			}//end switch 
			
			if(map.isTileAnExit(row, col)){
				exit = map.getTheExit();
				map = this.loadMap(exit.getExitFileName());
				avatar.setCol(exit.getPlayerDisembarkCol());
				avatar.setRow(exit.getPlayerDisembarkRow()); } //end if
			this.repaint();
			
			playersCurrentPoint.y = row;
			playersCurrentPoint.x = col;
		return playersCurrentPoint;
		
	}//end end moveDirection()



	public int getScale() {
		return scale;
	}



	public void setScale(int scale) {
		this.scale = scale;
	}
	
		

}// end class